#region Imported Namespaces

using System;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Data;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.WebControls;

using PHSRAG.Insight21.SearchContext;
using DataAccess = PHSRAG.Utility.DataAccess;
using SessionCachePolicy = PHSRAG.Insight21.Policy.SessionCachePolicy;
using Policy = PHSRAG.Insight21.Policy;
using UserContext = PHSRAG.Insight21.Context.UserContext;
using Constants = PHSRAG.Insight21.InsightUtilities.Constants;
#endregion

namespace PHSRAG.Insight21.InsightWebControls
{
	#region Class ExpiredAndExceptionSearch
	/// <summary>
	/// The ExpiredAndExceptionSearch control is used by expired fund allocation page.
	/// </summary>
	[ToolboxData("<{0}:ExpiredAndExceptionSearch runat=server />"), Designer(typeof(ExpiredAndExceptionSearchDesigner))]
	public class ExpiredAndExceptionSearch : BaseSearch, INamingContainer, ISearch
	{
		#region Constants 
		private const string ItemNameColumnName = "ItemName"; 
		private const string AllOptionValue             = "All"; 
		#endregion 		
		
		#region Instance Variables
		private Policy.ICachePolicy	cachePolicy;
	
		private PHSRAG.WebControls.Calendar	effectiveSalaryDateFrom;
		private PHSRAG.WebControls.Calendar	effectiveSalaryDateTo;
		private PHSRAG.WebControls.Calendar payDateFrom;
		private PHSRAG.WebControls.Calendar payDateTo;
		private TextBox		fundNumber;
		private DropDownList projectEndingDate;
		private DropDownList exceptionMessages;

		private bool fundNumberVisible			= true;
		private bool payDateVisible				= true;
		private bool effectiveSalaryDateVisible = true;
		private bool projectEndingDateVisible	= true;
		private bool exceptionMessagesVisible	= true;

		private ControlCollection controlCollection;
		#endregion

		#region ISearch Members
		/// <summary>
		/// Reset the internal search state. This involves setting the value for all controls to their default values
		/// and resetting the cached state of the search context.
		/// </summary>
		public void Reset()
		{
			ResetControls(controlCollection);
			
			if (effectiveSalaryDateVisible)
			{
				effectiveSalaryDateFrom.Reset();
				effectiveSalaryDateTo.Reset();
			}

			if (payDateVisible)
			{
				payDateFrom.Reset();
				payDateTo.Reset();
			}

			PersonnelSearchContext searchContext = cachePolicy.
				GetCachedObject(PersonnelSearchContext.CacheKey) as PersonnelSearchContext;
			if (searchContext != null)
				searchContext.Reset(Page.Request.Url.ToString());
		}

		/// <summary>
		/// Get the search criteria from the common search context.
		/// </summary>
		public SearchCriteria SearchCriteria
		{
			get
			{
				return ((PersonnelSearchContext)cachePolicy.GetCachedObject(PersonnelSearchContext.CacheKey)).GetSearchCriteria(Page.Request.Url.ToString());
			}
		}

		/// <summary>
		/// Get the search criteria. This is done by collecting the current values in all controls, storing them in the
		/// PersonnelSearchContext, and then returning the search criteria.
		/// </summary>
		public SearchCriteria UpdateSearchCriteria()
		{
			UserContext userContext = (UserContext)cachePolicy.GetCachedObject(UserContext.CacheKey);
			return GetSearchCriteria(userContext.DomainUserId, controlCollection);
		}
		#endregion

		#region Private Properties
		/// <summary>
		/// Determine if the control is in design mode. It is if there is not HTTP context.
		/// </summary>
		private static bool IsDesignMode
		{
			get { return HttpContext.Current == null; }
		}
		#endregion

		#region Public Properties
		/// <summary>
		///  Get/Set the visibility of the fund number Search Filter.
		/// </summary>
		public bool FundNumberVisible
		{
			get { return fundNumberVisible;  }
			set { fundNumberVisible = value;}
		}
		/// <summary>
		/// Get/Set the visibility of the PayDate search Filter
		/// </summary>
		public bool PayDateVisible
		{
			get { return payDateVisible;  }
			set { payDateVisible = value;}
		}

		/// <summary>
		/// Get/Set the visibility of the Effective Date search Filter
		/// </summary>
		public bool EffectiveSalaryDateVisible
		{
			get { return effectiveSalaryDateVisible ;  }
			set { effectiveSalaryDateVisible = value;}
		}
		/// <summary>
		/// Get/Set the visibility of the Project ending Date search Filter
		/// </summary>
		public bool ProjectEndingDateVisible
		{
			get { return projectEndingDateVisible ;  }
			set { projectEndingDateVisible = value;}
		}
		/// <summary>
		/// Get/Set the visibility of the Exception messages search Filter
		/// </summary>
		public bool ExceptionMessagesVisible
		{
			get { return exceptionMessagesVisible ;  }
			set { exceptionMessagesVisible = value;}
		}
		#endregion

		#region Overrides
		/// <summary>
		/// Create all controls. Notice that the creation is more than just instantiating the controls. It also involves
		/// in generating the underlying HTML so that the controls shows up per the need.
		/// </summary>
		protected override void CreateChildControls()
		{
			CreateControls();
			GenerateControlTree();
		}

		protected override void OnInit(EventArgs e)
		{
			cachePolicy = (Policy.ICachePolicy)Page.Session[Policy.Names.CachePolicyKey];
			PersonnelSearchContext searchContext = cachePolicy.
				GetCachedObject(PersonnelSearchContext.CacheKey) as PersonnelSearchContext;
			if (searchContext == null)
			{
                searchContext = new PersonnelSearchContext(cachePolicy);
			}

			EnsureChildControls();
			base.OnInit(e);
			searchContext.GetSearchCriteria(Page.Request.Url.ToString(), controlCollection);
		}

		/// <summary>
		/// Initialize the contents of all controls on first load. If the PersonnelSearchContext is not cached yet, a
		/// new instance is created and cached.
		/// </summary>
		/// <param name="e">Argument associated with the event</param>
		protected override void OnLoad(EventArgs e)
		{
			cachePolicy = (Policy.ICachePolicy)Page.Session[Policy.Names.CachePolicyKey];

			if (!Page.IsPostBack)
			{
				EnsureChildControls();

				PersonnelSearchContext searchContext = cachePolicy.
					GetCachedObject(PersonnelSearchContext.CacheKey) as PersonnelSearchContext;
				if (searchContext == null)
				{
                    searchContext = new PersonnelSearchContext(cachePolicy);
					searchContext.Load(DataAccess.ConnectionString);
					searchContext.Cache();
				}

				SetControlState(searchContext.GetSearchCriteria(Page.Request.Url.ToString(), controlCollection));
			}
		}

        /// <summary>
        /// Set the state for all constituent controls, and register a client script block for the express purpose of
        /// validating the date ranges of all paired Calendar controls in this search block.
        /// </summary>
        /// <param name="e">Argument associated with the event</param>
        /// <remarks>
        /// <protocolId>Why are the actions taken in this method not being done on control load?</protocolId>
        /// <protocolId>During the non-postback construction of the control, the OnLoad method is invoked BEFORE the
        /// CreateChildControls method. The actual creation of constitutent controls are done within the context of
        /// the CreateChildControls methos. Setting the state of control relies on (obviously) the fact that the controls
        /// have been created. So, setting the state in OnLoad for the non-postback condition would fail.</protocolId>
        /// <protocolId>Interestingly, the sequence of method invocations reverses on postback: CreateChildControls is invoked
        /// before OnLoad.</protocolId>
        /// </remarks>
        protected override void OnPreRender(EventArgs e)
        {
            if (!IsDesignMode)
            {
                if (!Page.ClientScript.IsClientScriptBlockRegistered(Constants.ValidateDateRangeScriptKey))
                {
                    string script = string.Format(
                        "<script language=\"javascript\">\n" +
                        "function ValidateDateRange()\n" +
                        "{{\n" +
                        "\tif (document.getElementById(\"{0}\") != null)\n" +
                        "\t\tvar effectiveSalaryFromText = document.getElementById(\"{0}\").value;\n" +
                        "\tif (document.getElementById(\"{1}\") != null)\n" +
                        "\t\tvar effectiveSalaryToText = document.getElementById(\"{1}\").value;\n" +
                        "\tif (document.getElementById(\"{2}\") != null)\n" +
                        "\t\tvar payFromText = document.getElementById(\"{2}\").value;\n" +
                        "\tif (document.getElementById(\"{3}\") != null)\n" +
                        "\t\tvar payToText = document.getElementById(\"{3}\").value;\n" +
                        "\tif (effectiveSalaryFromText != null && effectiveSalaryFromText != \"\" && effectiveSalaryToText != null && effectiveSalaryToText != \"\")\n" +
                        "\t{{\n" +
                        "\t\tvar effectiveSalaryFromDate = new Date(effectiveSalaryFromText);\n" +
                        "\t\tvar effectiveSalaryToDate = new Date(effectiveSalaryToText);\n" +
                        "\t\tif (effectiveSalaryFromDate > effectiveSalaryToDate)\n" +
                        "\t\t{{\n" +
                        "\t\t\talert('Effective Salary From Date cannot be after Effective Salary To Date.');\n" +
                        "\t\t\tdocument.getElementById(\"{1}\").focus();\n" +
                        "\t\t\treturn false;\n" +
                        "\t\t}}\n" +
                        "\t\treturn true;\n" +
                        "\t}}\n" +
                        "\tif (payFromText != null && payFromText != \"\" && payToText != null && payToText != \"\")\n" +
                        "\t{{\n" +
                        "\t\tvar payFromDate = new Date(payFromText);\n" +
                        "\t\tvar payToDate = new Date(payToText);\n" +
                        "\t\tif (payFromDate > payToDate)\n" +
                        "\t\t{{\n" +
                        "\t\t\talert('Pay From Date cannot be after Pay To Date.');\n" +
                        "\t\t\tdocument.getElementById(\"{3}\").focus();\n" +
                        "\t\t\treturn false;\n" +
                        "\t\t}}\n" +
                        "\t\treturn true;\n" +
                        "\t}}\n" +
                        "\treturn true;\n" +
                        "}}\n" +
                        "</script>\n",
                        (effectiveSalaryDateFrom == null) ? "" : effectiveSalaryDateFrom.SelectedDateClientId,
                        (effectiveSalaryDateTo == null) ? "" : effectiveSalaryDateTo.SelectedDateClientId,
                        (payDateFrom == null) ? "" : payDateFrom.SelectedDateClientId,
                        (payDateTo == null) ? "" : payDateTo.SelectedDateClientId);

                    Page.ClientScript.RegisterClientScriptBlock(GetType( ), Constants.ValidateDateRangeScriptKey, script);
                }
            }

            base.OnPreRender (e);
        }

		/// <summary>
		/// Render the control. Note that we simply ensure that all child controls are created, and then delegate the
		/// call back to the base class.
		/// </summary>
		/// <param name="writer">The writer to use for rendering</param>
		protected override void Render(HtmlTextWriter writer)
		{
			EnsureChildControls();
			base.Render(writer);
		}
		#endregion

		#region Private Methods
		/// <summary>
		/// Create all controls in the CommonSearch.
		/// </summary>
		private void CreateControls()
		{
			Controls.Clear();
			controlCollection = new ControlCollection(this);
		
			if (effectiveSalaryDateVisible)
			{
				effectiveSalaryDateFrom = new PHSRAG.WebControls.Calendar();
				effectiveSalaryDateFrom.ID = "effectiveSalaryDateFrom";
				effectiveSalaryDateFrom.Prompt = CommonSearch.SelectPrompt;
				effectiveSalaryDateFrom.Attributes["Label"] = "Effective Salary Date From";
				controlCollection.Add(effectiveSalaryDateFrom);

				effectiveSalaryDateTo = new PHSRAG.WebControls.Calendar();
				effectiveSalaryDateTo.ID = "effectiveSalaryDateTo";
				effectiveSalaryDateTo.Prompt = CommonSearch.SelectPrompt;
				effectiveSalaryDateTo.Attributes["Label"] = "Effective Salary Date To";
				controlCollection.Add(effectiveSalaryDateTo);
			}

			if (fundNumberVisible)
			{
				fundNumber = new TextBox();
				fundNumber.ID = "fundNumber";
				fundNumber.CssClass = "DataInput";
				fundNumber.Attributes["Label"] = "Fund Number";
				controlCollection.Add(fundNumber);
			}

			if (payDateVisible)
			{
				payDateFrom = new PHSRAG.WebControls.Calendar();
				payDateFrom.ID = "payDateFrom";
				payDateFrom.Prompt = CommonSearch.SelectPrompt;
				payDateFrom.Attributes["Label"] = "Pay Date From";
				controlCollection.Add(payDateFrom);

				payDateTo = new PHSRAG.WebControls.Calendar();
				payDateTo.ID = "payDateTo";
				payDateTo.Prompt = CommonSearch.SelectPrompt;
				payDateTo.Attributes["Label"] = "Pay Date To";
				controlCollection.Add(payDateTo);
			}

			if (projectEndingDateVisible)
			{
				projectEndingDate = new DropDownList();
				projectEndingDate.ID = "viewByProjectsWithin";
				projectEndingDate.CssClass = "DataInput";
				projectEndingDate.Items.Add(CommonSearch.SelectPrompt);
				projectEndingDate.Items.Add(new ListItem("30 Days", "30"));
				projectEndingDate.Items.Add(new ListItem("60 Days", "60"));
				projectEndingDate.Items.Add(new ListItem("90 Days", "90"));
				projectEndingDate.Items.Add(new ListItem("Already Expired", "-1"));
				projectEndingDate.SelectedIndex = 0;
				projectEndingDate.Enabled = (projectEndingDate.Items.Count > 1);
				projectEndingDate.Attributes["Label"] = "View By Projects Within";
				controlCollection.Add(projectEndingDate);
			}

			if (exceptionMessagesVisible)
			{
				exceptionMessages = new DropDownList();
				exceptionMessages.ID = "exceptionMessage";
				exceptionMessages.CssClass = "DataInput";
				exceptionMessages.Items.Add(CommonSearch.SelectPrompt);
				exceptionMessages.Items.Add(new ListItem("All"));
				exceptionMessages.Items.Add(new ListItem("Allocated Pending Fund"));
				exceptionMessages.Items.Add(new ListItem("Allocated Inactive Fund"));
				exceptionMessages.Items.Add(new ListItem("Salary not allocated 100%"));
				exceptionMessages.Items.Add(new ListItem("Zero Salary Distribution amount"));
				exceptionMessages.Items.Add(new ListItem("Salary Over Allocated"));
				exceptionMessages.SelectedIndex = 0;
				exceptionMessages.Enabled = (exceptionMessages.Items.Count > 1);
				exceptionMessages.Attributes["Label"] = "Exception Message";
				controlCollection.Add(exceptionMessages);
			}
        }

		/// <summary>
		/// Setup the control tree to reflect the actual (and exact) layout of the controls within the CommonSearch.
		/// </summary>
		private void GenerateControlTree()
		{
            string searchClientId = ((Policy.ICachePolicy)Page.Session[Policy.Names.CachePolicyKey]).GetCachedObject(Constants.SearchButtonClientIDKey) as string;
            if (searchClientId == null)
                searchClientId = "expandingPanel_commonSearch_search";

			Table t = new Table();
//			t.BorderWidth = System.Web.UI.WebControls.Unit.Pixel(1);
//			t.BorderColor = System.Drawing.Color.Red;
			t.Attributes["onkeypress"] = String.Format("return ClickButton(event, '{0}')", searchClientId);
			t.CssClass = "Search";
			t.CellSpacing = t.CellPadding = 5;
			t.Width = Unit.Percentage(100);
			Controls.Add(t);

			TableRow r = new TableRow();
			t.Rows.Add(r);
			TableCell c = new TableCell();
			c.Attributes["align"] = "left";
			r.Cells.Add(c);	

			Table t1 = new Table();
			c.Controls.Add(t1);

			TableRow r1 = new TableRow();
			t1.Rows.Add(r1);

			if(effectiveSalaryDateVisible)
			{	
				TableCell r1c1 = new TableCell();
				r1.Cells.Add(r1c1);
				r1c1.Attributes["align"] = "right";
				r1c1.Attributes["valign"] = "bottom";
				r1c1.Text = "Effective Salary Date From:&nbsp;&nbsp;";

				TableCell r1c2 = new TableCell();
				r1.Cells.Add(r1c2);
				r1c2.Attributes["align"] = "left";
				r1c2.Attributes["valign"] = "top";
				r1c2.Controls.Add(new LiteralControl("&nbsp;&nbsp;&nbsp;"));
				r1c2.Controls.Add(effectiveSalaryDateFrom);
			
				TableCell r1c3 = new TableCell();
				r1.Cells.Add(r1c3);
				r1c3.Attributes["align"] = "right";
				r1c3.Attributes["valign"] = "bottom";
				r1c3.Text = "&nbsp;&nbsp;To:&nbsp;&nbsp;";

				TableCell r1c4 = new TableCell();
				r1.Cells.Add(r1c4);
				r1c4.Attributes["align"] = "left";
				r1c4.Attributes["valign"] = "top";
				r1c4.Controls.Add(new LiteralControl("&nbsp;&nbsp;"));
				r1c4.Controls.Add(effectiveSalaryDateTo);

				TableCell r1c5 = new TableCell();
				r1.Cells.Add(r1c5);
				r1c5.Text = "&nbsp;&nbsp;";
			}

			if(payDateVisible)
			{
				TableCell space = new TableCell();
				r1.Cells.Add(space);
				space.Text = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";

				TableCell per1c5 = new TableCell();
				r1.Cells.Add(per1c5);
				per1c5.Attributes["align"] = "right";
				per1c5.Attributes["valign"] = "bottom";
				per1c5.Text = "Pay Date From:";

				TableCell space2 = new TableCell();
				r1.Cells.Add(space2);
				space2.Text = "&nbsp;";

				TableCell per1c6 = new TableCell();
				r1.Cells.Add(per1c6);
				per1c6.Attributes["align"] = "left";
				per1c6.Attributes["valign"] = "middle";
				per1c6.Controls.Add(new LiteralControl("&nbsp;&nbsp;"));
				per1c6.Controls.Add(payDateFrom);
			
				TableCell space3 = new TableCell();
				r1.Cells.Add(space3);
				space3.Text = "&nbsp;&nbsp;&nbsp;&nbsp;";

				TableCell per1c7 = new TableCell();
				r1.Cells.Add(per1c7);
				per1c7.Attributes["align"] = "right";
				per1c7.Attributes["valign"] = "bottom";
				per1c7.Text = "To:";

				TableCell per1c8 = new TableCell();
				r1.Cells.Add(per1c8);
				per1c8.Text = "&nbsp;";

				TableCell per1c9 = new TableCell();
				r1.Cells.Add(per1c9);
				per1c9.Attributes["align"] = "left";
				per1c9.Attributes["valign"] = "bottom";
				per1c9.Controls.Add(payDateTo);
			}

			if(fundNumberVisible)
			{
				TableCell space = new TableCell();
				r1.Cells.Add(space);
				space.Text = "&nbsp;&nbsp;&nbsp;";

				TableCell per1c3 = new TableCell();
				r1.Cells.Add(per1c3);
				per1c3.Attributes["align"] = "right";
				per1c3.Attributes["valign"] = "bottom";
				per1c3.Text = "Fund #:";

				TableCell per1c4 = new TableCell();
				r1.Cells.Add(per1c4);
				per1c4.Attributes["align"] = "left";
				per1c4.Attributes["valign"] = "bottom";
				per1c4.Controls.Add(new LiteralControl("&nbsp;"));
				per1c4.Controls.Add(fundNumber);
				per1c4.Controls.Add(new LiteralControl("&nbsp;&nbsp;"));

//				TableCell per1c3 = new TableCell();
//				per1.Cells.Add(per1c3);
//				per1c3.Attributes["align"] = "right";
//				per1c3.Text = "Fund#: ";
//
//				TableCell per1c4 = new TableCell();
//				per1.Cells.Add(per1c4);
//				per1c4.Attributes["align"] = "left";
//				per1c4.Controls.Add(new LiteralControl("&nbsp;&nbsp;"));
//				per1c4.Controls.Add(fundNumber);
//				per1c4.Controls.Add(new LiteralControl("&nbsp;&nbsp;"));
			}

			if(exceptionMessagesVisible)
			{
				TableRow emRow = new TableRow();
				t.Rows.Add(emRow);
				TableCell emCell = new TableCell();
				emCell.Attributes["align"] = "left";
				emRow.Cells.Add(emCell);		

				Table emTable = new Table();
				emCell.Controls.Add(emTable);

				TableRow emr1 = new TableRow();
				emTable.Rows.Add(emr1);

				TableCell emr1c1 = new TableCell();
				emr1.Cells.Add(emr1c1);
				emr1c1.Attributes["align"] = "right";
				emr1c1.Text = "Exception Messages: ";

				TableCell emr1c2 = new TableCell();
				emr1.Cells.Add(emr1c2);
				emr1c2.Attributes["align"] = "left";
				emr1c2.Controls.Add(new LiteralControl("&nbsp;&nbsp;"));
				emr1c2.Controls.Add(exceptionMessages);
			}

			TableRow peRow = new TableRow();
			t.Rows.Add(peRow);
			TableCell peCell = new TableCell();
			peCell.Attributes["align"] = "left";
			peRow.Cells.Add(peCell);		

			Table peTable = new Table();
			peCell.Controls.Add(peTable);

			TableRow per1 = new TableRow();
			peTable.Rows.Add(per1);

			if(projectEndingDateVisible)
			{
				TableCell per1c1 = new TableCell();
				per1.Cells.Add(per1c1);
				per1c1.Attributes["align"] = "right";
				per1c1.Text = "View Employee with Salary Planned on Projects Ending in: ";

				TableCell per1c2 = new TableCell();
				per1.Cells.Add(per1c2);
				per1c2.Attributes["align"] = "left";
				per1c2.Controls.Add(new LiteralControl("&nbsp;&nbsp;"));
				per1c2.Controls.Add(projectEndingDate);
				per1c2.Controls.Add(new LiteralControl("&nbsp;&nbsp;"));
			}		
		}
		#endregion

		#region Internal Methods
		/// <summary>
		/// This method is ONLY invoked by the associated designer to show the control contents at design time.
		/// </summary>
		internal void Design()
		{
			EnsureChildControls();
		}
		#endregion
	}
	#endregion

	#region Class PagerDesigner
	/// <summary>
	/// Designer associated with the ExpiredAndExceptionSearch control.
	/// </summary>
	/// <remarks>
	/// This class cannot be used directly.
	/// </remarks>
	public class ExpiredAndExceptionSearchDesigner : ControlDesigner
	{
		#region Overrides
		/// <summary>
		/// Force the control to create its child controls for display at design time.
		/// </summary>
		/// <returns>HTML representation of the control</returns>
		public override string GetDesignTimeHtml()
		{
			((ExpiredAndExceptionSearch)Component).Design();
			return base.GetDesignTimeHtml();
		}
		#endregion
	}
	#endregion
}

// --- EOF ---
